#pragma once
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <atomic>
#include <future>

namespace timeout_manager {

/**
 * 简单的线程池实现
 * 用于执行用户提交的任务
 */
class ThreadPool {
public:
    using Task = std::function<void()>;  // 任务类型定义
    
    /**
     * 构造函数
     * @param numThreads 线程数量，默认为CPU核心数
     */
    explicit ThreadPool(size_t numThreads = std::thread::hardware_concurrency());
    
    /**
     * 析构函数
     * 会等待所有任务完成并清理资源
     */
    ~ThreadPool();
    
    /**
     * 提交任务到线程池
     * @param task 要执行的任务
     */
    void submit(Task task);
    
    /**
     * 提交任务并返回future（用于获取结果）
     * @param func 要执行的函数
     * @param args 函数参数
     * @return future对象，可以获取函数执行结果
     */
    template<typename F, typename... Args>
    auto submitWithResult(F&& func, Args&&... args) 
        -> std::future<decltype(func(args...))>;
    
    /**
     * 获取当前队列中等待执行的任务数量
     */
    size_t getQueueSize() const;
    
    /**
     * 检查线程池是否正在关闭
     */
    bool isShuttingDown() const { return shutdown_.load(); }
    
private:
    /**
     * 工作线程的主要逻辑
     * 不断从队列中取任务执行
     */
    void workerThread();
    
    std::vector<std::thread> workers_;        // 工作线程数组
    std::queue<Task> taskQueue_;             // 任务队列
    
    mutable std::mutex queueMutex_;          // 保护任务队列的互斥锁
    std::condition_variable condition_;       // 用于线程间同步的条件变量
    std::atomic<bool> shutdown_;             // 关闭标志（原子变量，线程安全）
};

/**
 * 提交带返回值的任务
 */
template<typename F, typename... Args>
auto ThreadPool::submitWithResult(F&& func, Args&&... args) 
    -> std::future<decltype(func(args...))> {
    
    using ReturnType = decltype(func(args...));  // 推导返回类型
    
    // 创建packaged_task，它可以包装函数并提供future
    auto task = std::make_shared<std::packaged_task<ReturnType()>>(
        std::bind(std::forward<F>(func), std::forward<Args>(args)...)
    );
    
    // 获取future用于返回
    auto future = task->get_future();
    
    // 提交任务到队列
    submit([task]() { (*task)(); });
    
    return future;
}

} // namespace timeout_manager